#详情页蓝图模块
from flask import Blueprint
from flask import render_template,request,redirect,url_for, jsonify
from models import House,User#导入用户模型
from settings import db
from sqlalchemy import func
from datetime import datetime,timedelta #导入是日期模块
from linearregression import linear_model_main
#创建蓝图对象
detail_page = Blueprint('detail_page',__name__)
#房源详情页路由
@detail_page.route('/house/<int:hid>')
def detail(hid):
    #1.查询对应的hid的房源对象，返回一个对象
    house = House.query.get(hid)
    #2.获取当前hid对象中的所有配套设施，并使用split('-')拆分成列表
    #3.给当前登录的用户添加浏览记录
    name = request.cookies.get('name')
    if name:
        user = User.query.filter(User.name==name).first()
        seen_id_str = user.seen_id
        if seen_id_str:#有记录，把当前id追加到记录字符串后面
            seen_id_list = seen_id_str.split(',')
            set_id = set([int(i) for i in seen_id_list])#列表推导式
            if hid not in set_id:
                user.seen_id = seen_id_str + ','+str(hid)
                db.session.commit()
            else:
                user.seen_id = str(hid)
                db.session.commit()
        else:
            seen_id_str = str(hid)
            db.session.commit()
    else:
            facilities = house.facilities.split('-')
    return render_template('detail_page.html',house=house,
                           facilities=facilities)

#户型占比可视化路由
@detail_page.route('/get/piedata/<block>')
def return_pie_data(block):
    #1.根据当前房源的街区中的户型和数量，分组，再按数量降序排序
    result = House.query.with_entities(House.rooms,func.count()).\
             filter(House.block==block).group_by(House.rooms).\
             order_by(func.count().desc()).all()
    #print(result)#[(户型，数量),()……]
    #2.将查询结果组装成json格式，返回给前端
    '''
    {
        "data":[
               {"name":"1室1厅","value"：100},{},{}……
        ]
    }
    '''
    data = []
    for rooms,num in result:
        data.append({"name":rooms,"value":num})
    return jsonify({"data":data})

#小区房源数量top20可视化路由
@detail_page.route('/get/columndata/<block>')
def return_bar_data(block):
    #1.根据当前房源的街区中的小区和数量，分组，再按数量降序排序，取前20小区
    result = House.query.with_entities(House.address,func.count()).\
             filter(House.block==block).group_by(House.address).\
             order_by(func.count().desc()).limit(20).all()
    #2.组装成前端需要的json格式
    name_list_x = []
    num_list_y = []
    for addr,num in result:
        name_list_x.append(addr.split('-')[2])
        num_list_y.append(num)
    #3.返回json数据
    return jsonify({"data":{"name_list_x":name_list_x,
                            "num_list_y":num_list_y
                            }
                    })

#户型价格走势可视化路由
@detail_page.route('/get/brokenlinedata/<block>')
def return_brokenline_data(block):
    #1.根据当前房源的街区获取时间序列
    #查询出降序的发布时间
    time_stamp = House.query.with_entities(House.publish_time).\
                 filter(House.block==block).\
                 order_by(House.publish_time.desc()).all()
    #通过最新时间向前推算14天
    date_li = []
    for i in range(1,14):
        #获取最新时间
        latest_release = datetime.fromtimestamp(int(time_stamp[0][0]))
        #通过最新时间向前推算
        day = latest_release + timedelta(days=-i)
        #将时间格式化成月-日，存进date_li
        date_li.append(day.strftime('%m-%d'))
    date_li.reverse()

    #2.根据当前房源的街区获取户型的价格
    #1室1厅
    result = House.query.with_entities(func.avg(House.price/House.area)).\
             filter(House.block==block,House.rooms=='1室1厅').\
             group_by(House.publish_time).\
             order_by(House.publish_time).all()
    data = []
    for i in result[-14:]:
        data.append(round(i[0],2))

    #2室1厅
    result1 = House.query.with_entities(func.avg(House.price/House.area)).\
             filter(House.block==block,House.rooms=='2室1厅').\
             group_by(House.publish_time).\
             order_by(House.publish_time).all()
    data1 = []
    for i in result1[-14:]:
        data1.append(round(i[0],2))

    #2室2厅
    result2 = House.query.with_entities(func.avg(House.price/House.area)).\
             filter(House.block==block,House.rooms=='2室2厅').\
             group_by(House.publish_time).\
             order_by(House.publish_time).all()
    data2 = []
    for i in result2[-14:]:
        data2.append(round(i[0],2))

    #3室2厅
    result3 = House.query.with_entities(func.avg(House.price/House.area)).\
             filter(House.block==block,House.rooms=='3室2厅').\
             group_by(House.publish_time).\
             order_by(House.publish_time).all()
    data3 = []
    for i in result3[-14:]:
        data3.append(round(i[0],2))

    #3.组装数据到前端
    return jsonify({"data":{
                        "1室1厅":data,
                        "2室1厅":data1,
                        "2室2厅":data2,
                        "3室2厅":data3,
                        "date_li":date_li
                  }})


#预测房价走势可视化路由
@detail_page.route('/get/scatterdata/<block>')
def return_scatter_data(block):
    #1.获取当前街区的时间和价格序列
    #获取价格
    result = House.query.with_entities(func.avg(House.price/House.area)).\
             filter(House.block==block).\
             group_by(House.publish_time).\
             order_by(House.publish_time).all()
    #获取时间
    time_stamp = House.query.with_entities(House.publish_time).\
                 filter(House.block==block).all()
    time_stamp.sort(reverse=True)
    #找到最新时间向前推算近一个月时间
    date_li = []
    for i in range(1,30):
        #获取最新时间
        latest_release = datetime.fromtimestamp(int(time_stamp[0][0]))
        #通过最新时间向前推算
        day = latest_release + timedelta(days=-i)
        #将时间格式化成月-日，存进date_li
        date_li.append(day.strftime('%m-%d'))
    date_li.reverse() #反转当前的排序，升序

    #2.组装训练和预测的数据
    data = [] #返回前端的带日期的序号和价格的二维列表
    x = [] #做训练的自变量，是每天日期的序号
    y = [] #做训练的因变量，是每天的价格
    for index,i in enumerate(result):
        x.append([index]) #二维
        y.append(round(i[0],2))
        data.append([index,round(i[0],2)])

    #3.调用模型进行训练和预测
    predict_value = len(data)
    predict_outcome = linear_model_main(x,y,predict_value)
    p_outcome = round(predict_outcome[0],2)
    data.append([predict_value,p_outcome])

    #4.返回组装json数据给前端
    return jsonify({"data":{
                            "data-predict":data,
                            "date_li":date_li
                }})

#自定义过滤器，过滤交通条件为空的情况
def deal_empty(word):
    if len(word) == 0 or word is None:
        return '暂无信息！'
    else:
        return word

detail_page.add_app_template_filter(deal_empty,'dealempty')
